#include <sstream>
#include <string_view>
#include <thread>
#include <unordered_map>
#include <vector>

class Script final {
public:
  Script(std::string_view cmds, const std::unordered_map<std::string, std::string> &variables);
  void runScript();

  ~Script();

  static void runCmdStr(std::string_view);

  template <typename... Args> static void runCmd(const Args &...args) {
    std::ostringstream cmd;
    ((cmd << args), ...); // fold expression

    runCmdStr(cmd.str());
  }

private:
  void scriptSwitch(std::string_view cmd);
  std::string_view getVar(std::string_view varName) const;
  void JoinAndClearThreads();

  std::vector<std::thread> cmdThreads_;
  std::vector<std::string> cmds_;
  const std::unordered_map<std::string, std::string> &variables_;
};
